/**
 * @author 艾尼亚尔
 * @date 2025/8/15
 * @description 请求二次封装
 */

import {
    isUrl,
    joinTimestamp,
    type CreateAxiosOptions,
    type Result,
    type RetryConfig,
    type Recordable
} from './help.ts';
import type {AxiosRequestConfig, AxiosResponse} from 'axios';
import {AxiosError} from 'axios';
import {AxiosTransform} from './transformAxios.ts';
import {AxiosService} from './AxiosService.ts'
import type {MessageApi} from 'naive-ui';
import {getToken} from '@/utils/storage.ts'
import {config as configSett} from "@/config";
import {userStoreWidthOut} from "@/stores/user.ts";


const transformResponseData = <T>(res: AxiosResponse<Result<T>>): Result<T> => res.data;

const retryConfig: RetryConfig = {
    retries: 3, // 最大重试次数
    retryDelay: 1000, // 重试间隔时间（毫秒）
    retryableStatus: [408, 429, 500, 502, 503, 504], // 需要重试的状态码
};

/**
 * 统一的 Axios 请求/响应转换与拦截器配置
 */
const transformAxios: AxiosTransform = {
    /**
     * 请求前处理
     * 1. 拼接 urlPrefix
     * 2. 可选添加时间戳防止缓存
     * 3. 返回处理后的 config
     */
    beforeRequestHook(
        config: AxiosRequestConfig,
        options: CreateAxiosOptions
    ): AxiosRequestConfig {
        const {urlPrefix = '', joinTime = true} = options;

        // 1. 拼接统一前缀
        if (urlPrefix && !isUrl(config.url)) {
            config.url = `${urlPrefix}${config.url}`;
        }

        // 2. 添加时间戳参数
        if (joinTime) {
            const ts = joinTimestamp(true, false);
            config.params = {
                ...(config.params as Record<string, unknown> || {}),
                ...(typeof ts === 'object' ? ts : {}),
            };
        }
        return config;
    },

    /**
     * 请求拦截器（可在此注入 token 等）
     */
    requestInterceptors(config: AxiosRequestConfig): AxiosRequestConfig {
        // 统一加 token 或其他 header
        const token = getToken();
        config.headers = config.headers || {};
        if (token) {
            config.headers['Authorization'] = `${configSett.TOKEN_PREFIX}${token}`;
        }
        //实现无感刷新token
        const userStore = userStoreWidthOut();
        if(userStore.willExpireSoon()){
             userStore.refreshToken()
        }

        return config;
    },

    /** 响应数据：直接返回后端约定的 Result<T> */
    transformResponseData,

    /**
     * 响应拦截器（可在此做全局数据结构适配）
     */
    responseInterceptors(res: AxiosResponse): AxiosResponse {
        return res;
    },

    /**
     * 响应错误统一处理
     */
    responseInterceptorsCatch(error: Error | AxiosError): Promise<Recordable> {
        const axiosError = error as AxiosError<Result>;

        const status = axiosError.response?.status;
        const data = axiosError.response?.data;

        const Message = (window as Window & { $message?: MessageApi }).$message;

        if (!Message) {
            return Promise.reject(data || error);
        }
        /* 状态码处理 */
        switch (status) {
            case 400:
                Message.error(data?.message || '操作失败', {duration: 1500});
                break;
            case 401:
                Message.warning(data?.message || '操作失败', {
                    duration: 1500, async onLeave() {
                        const userStore = userStoreWidthOut();
                        // 直接使用原生跳转，最可靠
                        userStore.clearStorage();
                        setTimeout(() => {
                            window.location.href = '/login';
                        }, 500);
                    }
                });
                break;
            case 422:
                Message.error(data?.message || '参数错误', {duration: 1500});
                break;
            case 403:
                Message.error(data?.message || '无权限操作', {duration: 1500});
                break;
            case 404:
                Message.error(data?.message || '不存在的请求', {duration: 1500});
                break;
            case 500:
                Message.error('服务器开小差了，请稍后再试！', {duration: 1500});
                break;
            default:
                if (!axiosError.response) {
                    Message.warning('网络连接失败，请检查网络设置', {duration: 1500});
                }
        }
        // 返回后续 catch 处理
        return Promise.reject(data || error);
    },
};

/**
 * 默认 axios 实例配置
 */
const defaultOptions: CreateAxiosOptions = {
    urlPrefix: '/api/admin',
    joinTime: true,
    headers: {'Content-Type': 'application/json;charset=UTF-8'}, // 默认请求头
    transform: transformAxios, // 拦截器与钩子
    retry: retryConfig.retries,
    retryDelay: retryConfig.retryDelay,
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const http = new AxiosService(defaultOptions);

